<?php


namespace App\Console\Commands\Lib;


use Carbon\Carbon;

/**
 * 只需要一个日期的命令计划使用
 * Trait DataDate
 * @package App\Console\Commands\Lib
 */
trait ByDate
{
    /**
     * Carbon对象
     * @var Carbon
     */
    protected $dt;

    /**
     * 脚本拉取的时间范围
     * @var Carbon[]
     */
    protected $period;

    /**
     * 拉取前一天数据的时间范围，必须H:i:s格式，作为闭区间
     * @var array
     */
    private $rerunTimeRange = ['00:00' => '00:30'];

    /**
     * 获取拉取前一天数据的时间范围
     * @return array
     */
    public function getRerunTimeRange()
    {
        return $this->rerunTimeRange;
    }

    /**
     * 设置拉取前一天数据的时间范围
     * @param array $range
     */
    protected function setRerunTimeRange($range)
    {
        $this->rerunTimeRange = $range;
    }

    /**
     * 初始化拉取日期
     */
    private function initDate()
    {
        // 传参优先
        $date = call_user_func([$this, 'argument'], 'date');
        if ($date) {
            $this->dt = Carbon::parse($date)->startOfDay();
            return;
        }

        // 重跑区间
        $now = date('H:i');
        $rerunTimeRange = $this->getRerunTimeRange();
        foreach ($rerunTimeRange as $start => $end) {
            if ($start <= $now && $now <= $end) { // 判断是否拉取前一天数据
                $this->dt = Carbon::yesterday();
                return;
            }
        }

        $this->dt = Carbon::today();
    }

    /**
     * 获取目前时间应拉取数据的日期
     * @param bool $timestamp
     * @return false|string
     */
    protected function getDate($timestamp = false)
    {
        if (!$this->dt) {
            $this->initDate();
        }
        return $timestamp ? strtotime($this->dt) : $this->dt->toDateString();
    }

    /**
     * @return Carbon
     */
    protected function getDt()
    {
        if (!$this->dt) {
            $this->initDate();
        }
        return clone $this->dt;
    }

    /**
     * 初始化拉取范围
     */
    private function initPeriod()
    {
        $this->period = [$this->getDt(), $this->getDt()->endOfDay()];
    }

    /**
     * 获取时间区间
     * @param bool $timestamp
     * @return mixed
     */
    protected function getPeriod($timestamp = false)
    {
        if (!$this->period) {
            $this->initPeriod();
        }
        list($start, $end) = $this->period;
        return $timestamp ? [$start->timestamp, $end->timestamp] : [(string)$start, (string)$end];
    }

    /**
     * 获取几天前的日期
     * @param $days
     * @param bool $timestamp
     * @return int|string
     */
    protected function getDateAgo($days, $timestamp = false)
    {
        $date = $this->getDt()->subDays($days);
        return $timestamp ? $date->timestamp : $date->toDateString();
    }

    /**
     * 获取几天前的时间区间
     * @param $days
     * @param bool $timestamp
     * @param bool $isCurrent
     * @return array
     */
    protected function getPeriodAgo($days, $timestamp = false, $isCurrent = false)
    {
        $start = $this->getDt()->subDays($days);
        if($isCurrent){
            $end = $this->getDt()->endOfDay();
        } else {
            $end = $this->getDt()->subDays($days)->endOfDay();
        }

        if ($timestamp) {
            $start = $start->timestamp;
            $end = $end->timestamp;
        }
        return [(string)$start, (string)$end];
    }

    /**
     * 判断此时是否为重跑
     * @return bool
     */
    protected function isRerun()
    {
        return $this->getDate(true) < Carbon::today()->timestamp;
    }
}
